require 'yaml'

namespace :latisi do

  desc "Calculate classification accuracy"
  task :accuracy, :group, :needs => [:environment] do |t, args|
    as = Article.find_all_by_group(args.group)
    as.map { |a| printf "#{accuracy(a)}," }
  end    

  def accuracy(a)
    num_wrong = 0
    a.tblocks.each do |tb| 
      if tb.classification
        if tb.classification != tb.ml_class
          num_wrong += 1
        end
      end
    end
    num_right = a.tblocks.size - num_wrong
    num_right.to_f / a.tblocks.size.to_f
  end

  desc "Export an article into .lat format"
  task :export, :article_id, :needs => [:environment] do |t, args|
    a = Article.find(args.article_id)
    xml = a.to_xml :include => {:pages => {}, :tblocks => { :include => [:nf_rect]}}
    pdfpath = a.pdf.path
    xmlpath = a.xml.path
    featurespath = a.features.path
    Dir.mkdir("article-#{args.article_id}.lat")
    Dir.chdir("article-#{args.article_id}.lat") do |path|
      f = File.new("article.xml", "w")
      f.puts xml + "\n"
      f.close
      FileUtils.copy(pdfpath, ".") if pdfpath
      FileUtils.copy(xmlpath, ".") if xmlpath
      FileUtils.copy(featurespath, ".") if featurespath
      if not a.pages.empty?
        Dir.mkdir("pages")
        a.pages.each do |page|
          pagepath = page.page_image.path
          FileUtils.copy(pagepath, "./pages") if pagepath
        end
      end
    end
  end

  desc "Import an article in .lat format"
  task :import, :article_path, :needs => [:environment] do |t, args|
    a = Article.from_xml YAML::load(File.open("#{args.article_path}/article.xml"))
    a.save
    # hack to fix page_id association
    a.tblocks.each { |tb| tb.page_id = a.pages.find_by_number(tb.p).id ; tb.save }
    pdf = File.join(args.article_path, a.pdf_file_name) if a.pdf_file_name
    xml = File.join(args.article_path, a.xml_file_name) if a.xml_file_name
    features = File.join(args.article_path, a.features_file_name) if a.features_file_name

    a.pdf = File.open(pdf) if pdf and File.exist?(pdf)
    a.xml = File.open(xml) if xml and File.exist?(xml)
    a.features = File.open(features) if features and File.exist?(features)
    a.pages.each do |page|
      page_image = File.join(args.article_path, "pages", page.page_image_file_name) if page.page_image_file_name
      page.page_image = File.open(page_image)
      page.save
    end
    a.save
  end

  desc "Reset Latisi environment, including refreshing/seeding the database"
  task :reset => :environment do
    %w(drop create migrate).each do |task|
      puts "Performing db task #{task}"
      Rake::Task["db:#{task}"].invoke 
    end
    %w(clean_public seed_sections).each do |task|
      puts "Performing latisi task #{task}"
      Rake::Task["latisi:#{task}"].invoke
    end
  end

  desc "Seed database with section names defined in sections.yml"
  task :seed_sections => :environment do
    Section.all
    sections = YAML::load_file("#{RAILS_ROOT}/db/sections.yml")
    sections.each do |sec|
      Section.create(sec.attributes)
    end
  end

  desc "Delete old paperclip attachment files in public/<attachment_name>s directories"
  task :clean_public => :environment do
    attachment_dirs = %w(pdfs xmls features page_images)
    puts "cleaning public directory"
    attachment_dirs.each do |dir|
      Dir.glob("#{RAILS_ROOT}/public/system/#{dir}/*") do |id|
        if should_delete?(dir, File.basename(id))
          rm_rf(id)
        end
      end
    end
  end

end





def should_delete?(dir, id)
  case dir
  when *["pdfs", "xmls", "features"]
    res = article_check(id)
  when "page_images"
    res = page_check(id)
  end
  !res
end

def article_check(id)
  begin
    Article.find(id)
  rescue ActiveRecord::RecordNotFound
    return false
  end
  true
end

def page_check(id)
  begin
    Page.find(id)
  rescue ActiveRecord::RecordNotFound
    return false
  end
  true
end
